home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 005 / equity.arc / MODEHERC.ASM < prev    next >
Assembly Source File  |  1987-02-17  |  4KB  |  135 lines

  1.     page 60,132
  2. ;    Program to let SuperCalc 3, Lotus 123 1A and others
  3. ;    that may have problems successfully use Hercules
  4. ;    emulation on the Equity II.
  5. ;    Since this program remains resident, it is run only
  6. ;    once, and need not be run until the Equity II is
  7. ;    powered down or reset.
  8. ;    It is recommended that this program be the last resident
  9. ;    program in memory.
  10.  
  11. ;    DOS definitions
  12. dos        equ    21h        ;dos interrupt
  13. term_res    equ    31h        ;terminate but stay resident
  14. terminate    equ    4ch        ;terminate process
  15. set_vector    equ    25h        ;set interrupt vector
  16. get_vector    equ    35h        ;get interrupt vector
  17. display_str    equ    09        ;display string
  18. ;    Interrupt numbers
  19. video_int    equ    10h
  20. ;    Control characters
  21. cr        equ    0dh
  22. lf        equ    0ah
  23.  
  24. code        segment para 'CODE'
  25.  
  26.     assume    cs:code,ds:nothing,es:nothing,ss:nothing
  27.     org    100h
  28.  
  29. begin:    jmp    short start
  30.  
  31. modeherc    proc    far
  32.  
  33. new_video_int:        ;BIOS video (INT 10H) is redirected here.
  34.             ;Check to see if user program is requesting
  35.             ;set mono mode (AH=0, AL=7).
  36.  
  37.     cmp    ah,0        ;set video mode?
  38.     jnz    go_vid        ;no, just continue
  39.     cmp    al,7        ;set mono mode?
  40.     jnz    go_vid        ;if not, goto video int
  41.     pushf            ;set up for IRET from vid int
  42.     push    cs        ;same
  43.     mov    word ptr cs:ax_save,ax    ;save temporarily
  44.     mov    ax,offset continue    ;get continuation address 
  45.     push    ax            ;save it for IRET from video
  46.     mov    ax,word ptr cs:ax_save    ;restore user's AX
  47. go_vid:    jmp    dword ptr cs:old_video_int_off    ;go to real int 10h
  48.     
  49. continue:
  50.     push    dx
  51.     push    ax
  52.     mov    dx,03bfh    ;hercules configuration port
  53.     mov    al,03        ;graphics and page 1 can be used now
  54.     out    dx,al        ;set it
  55.     pop    ax
  56.     pop    dx
  57.     iret            ;back to user
  58.  
  59. sig_offset    equ    $ - new_video_int
  60. res_sig:    db    'Modeherc'
  61. sig_len        equ    $ - res_sig
  62.  
  63. ax_save:    dw    ?
  64. return_off:    dw    ?
  65. return_seg:    dw    ?
  66.  
  67. old_video_int_off:    dw    ?
  68. old_video_int_seg:    dw    ?
  69. last        equ    $-1    ;mark end of resident code
  70. modeherc    endp
  71.  
  72.     assume ds:code
  73. start    proc near    ;redirect video int to point to
  74.             ;new_video_int and save current vector
  75.  
  76.     mov    sp,offset stack
  77.     call    chk_res        ;see if we're resident already
  78.                 ;returns interrupt address in ES:BX
  79.  
  80.     mov    word ptr old_video_int_off,bx        ;store offset
  81.     mov    word ptr old_video_int_seg,es        ;store segment
  82.  
  83.     mov    dx,offset new_video_int        ;DS:DX is now new int address
  84.     mov    al,video_int    ;video interrupt #
  85.     mov    ah,set_vector    ;set vector func
  86.     int    dos        ;set int 10h to new_video_int
  87.  
  88.     mov    ax,7        ;reset mono mode before
  89.     int    10h        ;leaving so hercules is in full mode
  90.  
  91.     mov    dx,offset last    ;byte count of code to stay resident
  92.     mov    cl,4
  93.     shr    dx,cl        ;change to paragraph count
  94.     inc    dx        ;just to be sure
  95.     mov    ah,term_res
  96.     mov    al,0        ;return code of 0
  97.     int    dos        ;that's all folks
  98. start    endp
  99.  
  100. chk_res        proc near    ;check if modeherc routine resident
  101.                 ;if not, returns current video interrupt
  102.                 ;in ES:BX
  103.     mov    ah,get_vector
  104.     mov    al,video_int    ;video interrupt
  105.     int    dos        ;get video interrupt vector in es:bx
  106.     mov    di,sig_offset    ;offset of signature bytes from int offset
  107.     add    di,bx        ;add in interrupt offset
  108.     mov    si,offset res_sig    ;point to sig bytes
  109.     mov    cx,sig_len    ;length of sig
  110.     cld
  111.     repz    cmpsb        ;is it there?
  112.     jz    its_there
  113.     ret            ;back to main program
  114.  
  115. its_there:    ;print already resident message
  116.     pop    ax
  117.     pop    ax
  118.     pop    ax        ;clean up stack
  119.  
  120.     mov    dx,offset there_mes
  121.     mov    ah,display_str
  122.     int    dos        ;display message
  123.     mov    ah,terminate    ;normal end of process
  124.     mov    al,0
  125.     int    dos        ;back to calling process
  126.  
  127. there_mes:
  128.     db    cr,lf,'Already resident ...',cr,lf,'$'
  129. chk_res        endp
  130.  
  131. stk:        db    16 dup('STACK...')
  132. stack        label    word
  133. code        ends
  134.         end    begin
  135.